<template>
  <el-main class="notice-main">
    <div class="container">
      <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave">
        <div v-show="showSearch" class="mb-[10px]">
          <el-card shadow="hover">
            <el-form ref="queryFormRef" :model="queryParams" :inline="true">
              <el-form-item label="通知标题" prop="title">
                <el-input v-model="queryParams.title" placeholder="请输入通知标题" clearable @keyup.enter="handleQuery" />
              </el-form-item>
              <el-form-item>
                <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
                <el-button icon="Refresh" @click="resetQuery">重置</el-button>
                <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()"> 删除 </el-button>
              </el-form-item>
            </el-form>
          </el-card>
        </div>
      </transition>

      <el-card shadow="hover" class="w-full">
        <el-table style="width: 100%" v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange">
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column label="通知标题" align="left" prop="title" :show-overflow-tooltip="true" min-width="150">
            <template #default="scope">
              <span>{{ scope.row.title }}</span>
            </template>
          </el-table-column>
          <el-table-column label="预警类型" align="center" prop="warnType" width="120">
            <template #default="scope">
              <el-tag :type="getWarnTypeTagType(scope.row.warnType)">
                {{ getWarnTypeName(scope.row.warnType) }}
              </el-tag>
            </template>
          </el-table-column>
          <!-- <el-table-column label="预警级别" align="center" prop="warnLevel" width="100">
            <template #default="scope">
              <el-tag :type="getWarnLevelType(scope.row.warnLevel)">
                {{ getWarnLevelName(scope.row.warnLevel) }}
              </el-tag>
            </template>
          </el-table-column> -->
          <el-table-column label="通知方式" align="center" prop="notifyMethod" width="200">
            <template #default="scope">
              <el-tag type="info">
                {{ getNotifyMethodName(scope.row.notifyMethod) }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="处理状态" align="center" prop="status" width="100">
            <template #default="scope">
              <el-tag :type="scope.row.status === 1 ? 'success' : 'warning'">
                {{ scope.row.status === 1 ? '已推送' : '未推送' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="创建用户" align="center" prop="userId" min-width="180">
            <template #default="scope">
              <span>{{ getUserName(scope.row.userId) }}</span>
            </template>
          </el-table-column>
          <el-table-column label="发送时间" align="center" prop="sendTime" min-width="170">
            <template #default="scope">
              <span>{{ formatDateTime(scope.row.sendTime) }}</span>
            </template>
          </el-table-column>
          <!-- <el-table-column label="来源" align="center" prop="source" width="120">
            <template #default="scope">
              <span v-if="!scope.row.eventId" class="source-text warning">预警通知</span>
              <el-link v-else type="danger" :underline="false" class="source-text event" @click="handleEventClick(scope.row.eventId)">
                事件通知
              </el-link>
            </template>
          </el-table-column> -->
          <el-table-column label="阅读状态" align="center" prop="readStatus" width="80">
            <template #default="scope">
              <el-tag :type="scope.row.readStatus === 1 ? 'success' : 'warning'">
                {{ scope.row.readStatus === 1 ? '已读' : '未读' }}
              </el-tag>
            </template>
          </el-table-column>
          <el-table-column label="操作" align="center" class-name="small-padding fixed-width" min-width="220">
            <template #default="scope">
              <el-button type="primary" link icon="View" @click="handleView(scope.row)"></el-button>
              <el-button v-if="scope.row.status === 0" type="success" link icon="Position" @click="handlePublish(scope.row)">推送 </el-button>
              <el-button
                :type="scope.row.readStatus === 1 ? '' : 'warning'"
                link
                :icon="scope.row.readStatus === 1 ? 'View' : 'Hide'"
                @click="handleReadStatus(scope.row)"
              >
                {{ scope.row.readStatus === 1 ? '标为未读' : '标为已读' }}
              </el-button>
              <el-button type="danger" link icon="Delete" @click="handleDelete(scope.row)"></el-button>
            </template>
          </el-table-column>
        </el-table>

        <pagination v-show="total > 0" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" :total="total" @pagination="getList" />
      </el-card>

      <!-- 查看预警通知详情对话框 -->
      <el-dialog v-model="viewDialog.visible" :title="viewDialog.title" width="1200px" append-to-body destroy-on-close>
        <div class="notice-header">
          <div class="notice-title">{{ currentNotice.title }}</div>
          <div class="notice-meta">
            <span class="notice-type">
              <el-tag :type="getWarnTypeTagType(currentNotice.warnType)" class="mr-2">
                {{ getWarnTypeName(currentNotice.warnType) }}
              </el-tag>
            </span>
            <span class="notice-level">
              <el-tag :type="getWarnLevelType(currentNotice.warnLevel)" class="mr-2">
                {{ getWarnLevelName(currentNotice.warnLevel) }}
              </el-tag>
            </span>
            <span class="notice-method">
              <el-tag type="info" class="mr-2">
                {{ getNotifyMethodName(currentNotice.notifyMethod) }}
              </el-tag>
            </span>
            <span class="notice-time">
              <i class="ri-time-line mr-1"></i>
              {{ formatDateTime(currentNotice.sendTime) }}
            </span>
          </div>
        </div>
        <el-divider />
        <div class="notice-content" v-html="currentNotice.content"></div>
        <template #footer>
          <div class="dialog-footer">
            <el-button v-if="currentNotice.status === 0" type="primary" @click="handlePublish(currentNotice)">推送通知 </el-button>
            <el-button @click="viewDialog.visible = false">关闭</el-button>
          </div>
        </template>
      </el-dialog>

      <!-- 添加预警通知对话框 -->
      <el-dialog v-model="dialog.visible" :title="dialog.title" width="1200px" append-to-body destroy-on-close>
        <el-form ref="noticeFormRef" :model="form" :rules="rules" label-width="100px">
          <el-row>
            <el-col :span="12">
              <el-form-item label="通知标题" prop="title">
                <el-input v-model="form.title" placeholder="请输入通知标题" />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="预警类型" prop="warnType">
                <el-select v-model="form.warnType" placeholder="请选择预警类型" style="width: 100%">
                  <el-option v-for="dict in warnTypeOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="预警级别" prop="warnLevel">
                <el-select v-model="form.warnLevel" placeholder="请选择预警级别" style="width: 100%">
                  <el-option v-for="dict in warnLevelOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
                </el-select>
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="通知方式" prop="notifyMethod">
                <el-select v-model="form.notifyMethod" placeholder="请选择通知方式" style="width: 100%" multiple>
                  <el-option v-for="dict in notifyMethodOptions" :key="dict.dictValue" :label="dict.dictLabel" :value="dict.dictValue" />
                </el-select>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="12">
              <el-form-item label="发送时间" prop="sendTime">
                <el-date-picker
                  v-model="form.sendTime"
                  type="datetime"
                  placeholder="请选择发送时间"
                  format="YYYY-MM-DD HH:mm:ss"
                  value-format="YYYY-MM-DD HH:mm:ss"
                  style="width: 100%"
                />
              </el-form-item>
            </el-col>
            <el-col :span="12">
              <el-form-item label="处理状态">
                <el-radio-group v-model="form.status">
                  <el-radio :label="1">立即推送</el-radio>
                  <el-radio :label="0">稍后推送</el-radio>
                </el-radio-group>
              </el-form-item>
            </el-col>
          </el-row>
          <el-row>
            <el-col :span="24">
              <el-form-item label="通知内容" prop="content">
                <editor v-model="form.content" :min-height="192" />
              </el-form-item>
            </el-col>
          </el-row>
        </el-form>
        <template #footer>
          <div class="dialog-footer">
            <el-button type="primary" @click="submitForm">确 定</el-button>
            <el-button @click="dialog.visible = false">取 消</el-button>
          </div>
        </template>
      </el-dialog>
    </div>
  </el-main>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, getCurrentInstance } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import dayjs from 'dayjs';
import Editor from '@/components/Editor/index.vue';
import type { ComponentInternalInstance } from 'vue';
import { listData } from '@/api/system/dict/data';
import { getNoticeList, getNoticeDetail, addNotice, updateNotice, deleteNotice, publishNotice } from '@/api/bridge/command/notice';
import { getUserInfoList } from '@/api/bridge/user/user';
import useUserStore from '@/store/modules/user';
import { useRouter } from 'vue-router';

const userStore = useUserStore();
const userId = userStore.userId;

const { proxy } = getCurrentInstance() as ComponentInternalInstance;

interface DictOption {
  dictValue: string;
  dictLabel: string;
  dictType?: string;
  cssClass?: string;
  listClass?: string;
}

interface UserInfo {
  userId: number;
  userName: string;
  nickName: string;

  [key: string]: any;
}

// 列表数据
const noticeList = ref<any[]>([]);
const loading = ref(false);
const total = ref(0);
const showSearch = ref(true);
const ids = ref<Array<number>>([]);
const single = ref(true);
const multiple = ref(true);
const userList = ref<UserInfo[]>([]);

// 字典数据
const warnTypeOptions = ref<DictOption[]>([]);
const warnLevelOptions = ref<DictOption[]>([]);
const notifyMethodOptions = ref<DictOption[]>([]);

// 查询参数
const queryParams = reactive({
  pageNum: 1,
  pageSize: 10,
  type: null,
  title: null
});

// 表单参数
const formInitData = {
  id: undefined,
  title: '',
  content: '',
  warnType: '',
  warnLevel: '',
  status: 0,
  notifyMethod: [],
  sendTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
  userId: undefined,
  type: undefined
};

const form = reactive({ ...formInitData });

// 表单校验规则
const rules = {
  title: [{ required: true, message: '通知标题不能为空', trigger: 'blur' }],
  warnType: [{ required: true, message: '预警类型不能为空', trigger: 'change' }],
  warnLevel: [{ required: true, message: '预警级别不能为空', trigger: 'change' }],
  content: [{ required: true, message: '通知内容不能为空', trigger: 'blur' }],
  notifyMethod: [{ required: true, message: '通知方式不能为空', trigger: 'change' }],
  sendTime: [{ required: true, message: '发送时间不能为空', trigger: 'change' }]
};

// 对话框参数
const dialog = reactive({
  visible: false,
  title: ''
});

// 查看对话框参数
const viewDialog = reactive({
  visible: false,
  title: '通知详情'
});

const currentNotice = ref<any>({});
const noticeFormRef = ref<any>(null);
const queryFormRef = ref<any>(null);

const router = useRouter();

// 获取通知列表
const getList = async () => {
  loading.value = true;
  try {
    //预警通知
    queryParams.type = 1;
    const res = await getNoticeList(queryParams);
    if (!res || res.data === null) {
      // 递归调用前先释放loading状态
      loading.value = false;
      return await getList();
    }
    noticeList.value = res.rows || [];
    total.value = res.total || 0;
  } catch (error) {
    console.error('获取通知列表失败:', error);
    ElMessage.error('获取通知列表失败');
  } finally {
    loading.value = false;
  }
};

// 获取字典数据
const getDictDataList = async (retryCount = 0) => {
  try {
    // 获取预警类型
    const warnTypeRes = await listData({
      dictType: 'warning_type',
      pageNum: 1,
      pageSize: 10,
      dictName: '',
      dictLabel: ''
    });
    if (!warnTypeRes || !warnTypeRes.rows) {
      if (retryCount < 3) {
        return await getDictDataList(retryCount + 1);
      }
      throw new Error('获取预警类型数据失败');
    }
    warnTypeOptions.value = warnTypeRes.rows;

    // 获取预警级别
    const warnLevelRes = await listData({
      dictType: 'warn_level',
      pageNum: 1,
      pageSize: 10,
      dictName: '',
      dictLabel: ''
    });
    if (!warnLevelRes || !warnLevelRes.rows) {
      if (retryCount < 3) {
        return await getDictDataList(retryCount + 1);
      }
      throw new Error('获取预警级别数据失败');
    }
    warnLevelOptions.value = warnLevelRes.rows;

    // 获取通知方式
    const notifyMethodRes = await listData({
      dictType: 'notification_method',
      pageNum: 1,
      pageSize: 10,
      dictName: '',
      dictLabel: ''
    });
    if (!notifyMethodRes || !notifyMethodRes.rows) {
      if (retryCount < 3) {
        return await getDictDataList(retryCount + 1);
      }
      throw new Error('获取通知方式数据失败');
    }
    notifyMethodOptions.value = notifyMethodRes.rows;
  } catch (error) {
    console.error('获取字典数据失败:', error);
    if (retryCount < 3) {
      return await getDictDataList(retryCount + 1);
    }
  }
};

// 获取用户列表
const getUserList = async (retryCount = 0) => {
  try {
    const params = {
      pageNum: 1,
      pageSize: 10
    };
    const res = await getUserInfoList(params);
    if (!res || !res.rows) {
      if (retryCount < 3) {
        return await getUserList(retryCount + 1);
      }
      throw new Error('获取用户列表数据失败');
    }
    userList.value = res.rows;
  } catch (error) {
    console.error('获取用户列表失败:', error);
    ElMessage.error('获取用户列表失败');
    if (retryCount < 3) {
      return await getUserList(retryCount + 1);
    }
  }
};

// 根据用户ID获取用户名称
const getUserName = (userId: number | null) => {
  if (!userId) return '-';
  const user = userList.value.find((user) => user.userId === userId);
  return user ? user.nickName || user.userName : `用户${userId}`;
};

// 格式化日期时间
const formatDateTime = (dateString: string) => {
  if (!dateString) return '-';
  return dayjs(dateString).format('YYYY-MM-DD HH:mm:ss');
};

// 获取预警类型标签类型
const getWarnTypeTagType = (type: string): 'success' | 'warning' | 'info' | 'primary' | 'danger' => {
  const typeMap: Record<string, 'success' | 'warning' | 'info' | 'primary' | 'danger'> = {
    'traffic': 'danger', // 交通事故预警
    'environmental': 'warning', // 环境污染预警
    'medical': 'info', // 公共卫生预警
    'weather': 'warning', // 气象灾害预警
    'geology': 'danger' // 地质灾害预警
  };
  return typeMap[type] || 'info';
};

// 获取预警类型标签文本
const getWarnTypeName = (type: string) => {
  const found = warnTypeOptions.value.find((item) => item.dictValue === type);
  return found ? found.dictLabel : type;
};

// 获取预警级别类型
const getWarnLevelType = (level: string): 'success' | 'warning' | 'info' | 'primary' | 'danger' => {
  const typeMap: Record<string, 'success' | 'warning' | 'info' | 'primary' | 'danger'> = {
    '1': 'danger',
    '2': 'danger',
    '3': 'warning',
    '4': 'info'
  };
  return typeMap[level] || 'info';
};

// 获取预警级别标签文本
const getWarnLevelName = (level: string) => {
  const found = warnLevelOptions.value.find((item) => item.dictValue === level);
  return found ? found.dictLabel : level;
};

// 获取通知方式名称
const getNotifyMethodName = (method: string) => {
  if (!method) return '-';
  // 确保 method 是一个数组，即使只有一个通知方式
  const methodArray = Array.isArray(method) ? method : method.split(',');
  return methodArray
    .map((m) => {
      const found = notifyMethodOptions.value.find((item) => item.dictValue === m);
      return found ? found.dictLabel : m;
    })
    .join('、');
};

// 多选框选中数据
const handleSelectionChange = (selection: any[]) => {
  ids.value = selection.map((item) => item.id);
  single.value = selection.length !== 1;
  multiple.value = !selection.length;
};

// 新增按钮操作
const handleAdd = () => {
  reset();
  dialog.visible = true;
  dialog.title = '添加通知';
  form.sendTime = dayjs().format('YYYY-MM-DD HH:mm:ss');
  form.userId = userId;
  // 如果已选择了过滤类型，则默认设置为该类型
  if (queryParams.type) {
    form.type = queryParams.type;
  }
};

// 查看按钮操作
const handleView = async (row: any, retryCount = 0) => {
  try {
    const { data } = await getNoticeDetail(row.id);
    if (!data) {
      if (retryCount < 3) {
        return await handleView(row, retryCount + 1);
      }
      throw new Error('获取通知详情数据失败');
    }
    // 确保 notifyMethod 是数组
    data.notifyMethod = data.notifyMethod ? (Array.isArray(data.notifyMethod) ? data.notifyMethod : data.notifyMethod.toString().split(',')) : [];
    currentNotice.value = data;
    viewDialog.visible = true;
  } catch (error) {
    console.error('获取通知详情失败:', error);
    ElMessage.error('获取通知详情失败');
    if (retryCount < 3) {
      return await handleView(row, retryCount + 1);
    }
  }
};

// 推送通知
const handlePublish = async (row: any, retryCount = 0) => {
  try {
    // 更新发送时间和状态
    const updateData = {
      id: row.id,
      status: 1,
      sendTime: dayjs().format('YYYY-MM-DD HH:mm:ss')
    };

    // 先更新状态和时间
    const updateRes = await updateNotice(updateData);
    if (!updateRes) {
      throw new Error('更新通知状态失败');
    }

    // 再执行推送
    const res = await publishNotice(row.id);
    if (!res) {
      if (retryCount < 3) {
        return await handlePublish(row, retryCount + 1);
      }
      throw new Error('推送通知失败');
    }

    ElMessage.success('通知已推送');
    getList();
    if (viewDialog.visible) {
      viewDialog.visible = false;
    }
  } catch (error) {
    console.error('推送通知失败:', error);
    ElMessage.error('推送通知失败');
    if (retryCount < 3) {
      return await handlePublish(row, retryCount + 1);
    }
  }
};

// 删除按钮操作
const handleDelete = async (row?: any, retryCount = 0) => {
  const noticeIds = row?.id || ids.value;
  if (!noticeIds || (Array.isArray(noticeIds) && noticeIds.length === 0)) {
    ElMessage.warning('请至少选择一条记录');
    return;
  }

  await ElMessageBox.confirm(`确认删除选中的预警通知吗？`, '提示', {
    confirmButtonText: '确定',
    cancelButtonText: '取消',
    type: 'warning'
  });

  const res = await deleteNotice(noticeIds);
  if (!res) {
    if (retryCount < 3) {
      return await handleDelete(row, retryCount + 1);
    }
    throw new Error('删除通知失败');
  }
  ElMessage.success('删除成功');
  await getList();
};

// 表单重置
const reset = () => {
  Object.assign(form, formInitData);
  noticeFormRef.value?.resetFields();
};

// 提交表单
const submitForm = () => {
  noticeFormRef.value?.validate(async (valid: boolean) => {
    if (valid) {
      const submitWithRetry = async (retryCount = 0) => {
        try {
          form.userId = userId;
          const formData = {
            ...form,
            notifyMethod: Array.isArray(form.notifyMethod) ? form.notifyMethod.join(',') : form.notifyMethod
          };
          let res;

          if (formData.id) {
            res = await updateNotice(formData);
          } else {
            res = await addNotice(formData);
            // 检查是否需要立即推送
            if (res && res.code === 200 && formData.status === 1) {
              // 立即推送
              await handlePublish({ id: res.data });
            }
          }

          if (!res) {
            if (retryCount < 3) {
              return await submitWithRetry(retryCount + 1);
            }
            throw new Error('提交数据失败');
          }

          ElMessage.success(formData.id ? '修改成功' : '新增成功');
          dialog.visible = false;
          getList();
        } catch (error) {
          console.error('提交失败:', error);
          ElMessage.error('提交失败');
          if (retryCount < 3) {
            return await submitWithRetry(retryCount + 1);
          }
        }
      };

      await submitWithRetry();
    }
  });
};

// 处理事件点击
const handleEventClick = (eventId: string) => {
  router.push(`/monitor/event?eventId=${eventId}`);
};

// 处理阅读状态
const handleReadStatus = async (row: any) => {
  try {
    const newStatus = row.readStatus === 1 ? 0 : 1;
    await updateNotice({
      ...row,
      readStatus: newStatus
    });
    row.readStatus = newStatus;
    ElMessage.success(`已${newStatus === 1 ? '标记为已读' : '标记为未读'}`);
  } catch (error) {
    console.error('更新阅读状态失败:', error);
    ElMessage.error('更新阅读状态失败');
  }
};

/** 搜索按钮操作 */
const handleQuery = () => {
  queryParams.pageNum = 1;
  getList();
};

const resetQuery = () => {
  // 在这里添加重置逻辑
  queryParams.title = null;
  queryFormRef.value?.resetFields();
  // 调用查询接口
  getList();
};

// 处理类型过滤
const handleTypeFilter = (type: number) => {
  if (queryParams.type === type) {
    // 如果当前已经选中了该类型，则取消选择
    queryParams.type = null;
  } else {
    // 否则选中该类型
    queryParams.type = type;
  }
  getList();
};

getList();
getDictDataList();
getUserList();
onMounted(() => {
  getList();
  getDictDataList();
  getUserList();
});
</script>

<style scoped lang="scss">
.notice-main {
  padding: 0;
  width: 100%;
  max-width: 100%;
}

.container {
  padding: 20px;
  box-sizing: border-box;
  width: 100%;
  max-width: 100%;
}

.header-section {
  text-align: center;
  margin-bottom: 30px;
}

.title-font {
  font-size: 2.2rem;
  color: var(--el-text-color-primary);
  font-weight: 600;
  letter-spacing: 2px;
  margin-bottom: 1rem;
}

.title-divider {
  width: 80px;
  height: 3px;
  background: #409eff;
  margin: 0 auto;
  border-radius: 2px;
}

.w-full {
  width: 100%;

  :deep(.el-card__body) {
    padding: 10px;
  }
}

.notice-header {
  padding: 0 0 10px 0;
}

.notice-title {
  font-size: 1.5rem;
  font-weight: 600;
  margin-bottom: 10px;
  color: var(--el-text-color-primary);
}

.notice-meta {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  align-items: center;
  color: var(--el-text-color-secondary);
}

.notice-content {
  padding: 20px 0;
  min-height: 200px;
  line-height: 1.6;
}

.dialog-footer {
  padding-top: 20px;
  text-align: right;
}

.mr-1 {
  margin-right: 4px;
}

.mr-2 {
  margin-right: 8px;
}

:deep(.el-dialog) {
  .el-dialog__body {
    padding: 20px 30px;
  }
}

:deep(.el-main) {
  padding: 0;
  width: 100%;
  max-width: 100%;
}

:deep(.el-card) {
  width: 100%;
  max-width: 100%;
}

.source-text {
  font-weight: bold;
  font-size: 14px;

  &.warning {
    color: #e6a23c;
  }

  &.event {
    color: #f56c6c;
  }
}

.filter-buttons {
  display: flex;
  gap: 10px;
  align-items: center;
  height: 100%;
}

.filter-btn {
  transition: all 0.3s;
}
</style>
